use actix_web::web;
use chrono::NaiveDateTime;
use serde::{Deserialize, Serialize};
use std::convert::TryFrom;

use crate::errors::CustomError;

// json -> entity 反序列化 Deserialize 涉及到新增或者修改字段信息，就需要反序列化操作
// entiry -> json 序列化 Serialize 读取的数据就转成成 json 返回就好，不设计到新增或修改字段，不需要反序列化操作

// 用于只是查询出来即可，直接序列化即可，不需要反序列化
#[derive(Debug, Serialize, Clone)]
pub struct Course {
  pub teacher_id: i32,
  pub id: i32,
  pub name: String,
  pub time: NaiveDateTime,

  pub description: Option<String>,
  pub language: Option<String>,
  pub price: Option<i32>,
}

// 用于需要新增或修改字段信息，直接反序列化即可，不需要序列化
#[derive(Debug, Deserialize, Clone)]
pub struct CreateCourse {
  pub teacher_id: i32,
  pub name: String,

  pub description: Option<String>,
  pub language: Option<String>,
  pub price: Option<i32>,
}

// impl From<web::Json<CreateCourse>> for CreateCourse {
//   fn from(course: web::Json<CreateCourse>) -> Self {
//     Self {
//       teacher_id: course.teacher_id,
//       name: course.name.clone(),
//       description: course.description.clone(),
//       language: course.language.clone(),
//       price: course.price,
//     }
//   }
// }

// 使用 TryFrom 好一些，可以自定义错误信息
impl TryFrom<web::Json<CreateCourse>> for CreateCourse {
  type Error = CustomError;

  fn try_from(course: web::Json<CreateCourse>) -> Result<Self, Self::Error> {
    Ok(Self {
      teacher_id: course.teacher_id,
      name: course.name.clone(),
      description: course.description.clone(),
      language: course.language.clone(),
      price: course.price,
    })
  }
}

#[derive(Debug, Clone, Deserialize)]
pub struct UpdateCourse {
  pub name: Option<String>,
  pub description: Option<String>,
  pub language: Option<String>,
}

// 使用 TryFrom 好一些，可以有自定义错误信息
impl TryFrom<web::Json<UpdateCourse>> for UpdateCourse {
  type Error = CustomError;

  fn try_from(course: web::Json<UpdateCourse>) -> Result<Self, Self::Error> {
    Ok(Self {
      name: course.name.clone(),
      description: course.description.clone(),
      language: course.language.clone(),
    })
  }
}
